package jarfinder;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;



public class JarFinder
{
   private HashSet<Listener> listeners = new HashSet<Listener>();
   private static FilenameFilter ff = new MyFileNameFilter();
   
   public void addListener(Listener l)
   {
      listeners.add(l);
   }
   /**
    * Method process.
    * @param file
    * @param search
    */ 
   private void process(File file, String search, StringBuilder result) throws IOException
   {
      if (file.isDirectory())
      {
         File[] list = file.listFiles(ff);
         for (int i=0 ; i<list.length ; i++)
            process(list[i], search, result); 
      }
      else if (ff.accept(file, file.getName()))
      {
         fireEvent(new Event(file.getName()));
         try {
	         JarFile jarFile = new JarFile(file);
	         Enumeration<JarEntry> enm = jarFile.entries();
	         while (enm.hasMoreElements())
	         {
	            String name = process(enm.nextElement(), search); 
	            if (name != null)
	               result.append("File '" + file.getCanonicalPath() + " contains: " + name + '\n');
	         }
         } catch (IOException e) {
        	 System.out.printf("Cannot open file: '%s'%n",file.getCanonicalPath());
         }
      }
   }
   private void fireEvent(Event event)
   {
      for (Listener l : listeners)
      {
         l.handleEvent(event);
      }
   }
   private static String process(JarEntry entry, String search) 
   {
      String name = entry.getName();
      if (name.indexOf(search)>=0)
         return name; 
      return null;
   }


   /* (non-Javadoc)
    * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
    */
   public String process(File file, String pattern) 
   {
      StringBuilder result = new StringBuilder();
      String patternString = pattern.replaceAll("\\.","/");
      result.append("Searching for: " + patternString + "\n"); 
      try
      {
         process(file, patternString, result);
         return result.toString();
      } 
      catch (IOException ex)
      {
         ex.printStackTrace ();
         return null;
      }
   }  
   public String processCount(File file, String pattern) 
   {
      StringBuilder result = new StringBuilder();
      String patternString = pattern.replaceAll("\\.","/");
      result.append("Searching for: " + patternString + "\n"); 
      try
      {
         processCount(file, patternString, result);
         return result.toString();
      } 
      catch (IOException ex)
      {
         ex.printStackTrace ();
         return null;
      }
   }  
   private void processCount(File file, String search, StringBuilder result) throws IOException
   {
      if (file.isDirectory())
      {
         File[] list = file.listFiles(ff);
         for (int i=0 ; i<list.length ; i++)
            processCount(list[i], search, result); 
      }
      else if (ff.accept(file, file.getName()))
      {
         fireEvent(new Event(file.getName()));
         try {
         JarFile jarFile = new JarFile(file);
         Enumeration<JarEntry> enm = jarFile.entries();
         int count = 0;
         while (enm.hasMoreElements())
         {
            String name = process(enm.nextElement(), search); 
            if (name != null)
            {
               count++;
            }
         }
         if (count>0)
         {
            result.append("File '" + file.getCanonicalPath() + ": " + count + '\n');
         }
         } catch (IOException e) {
        	 System.out.printf("Cannot open file '%s'%n", file.getCanonicalPath());
         }
      }
   }
}

class MyFileNameFilter implements FilenameFilter
{
   /**
    * @see java.io.FilenameFilter#accept(java.io.File, java.lang.String)
    */
   public boolean accept(File file, String name)
   {
      if (file.isDirectory ()) return true;
      return name.endsWith("jar");
   }
}

